/* porady.c -- korzysta z interfejsu "kolejka" */
#include <stdio.h>
#include <stdlib.h>					// dla funkcji rand() i srand()
#include <time.h>					// dla funckji time()
#include "kolejka.h"
#define MIN_W_GODZ 60.0
#define OKIENKO_NR 2				// liczba okienek
bool nowyklient(double x);			// czy jest nowy klient?
Pozycja czasklienta(long kiedy);	// ustawia parametry klienta
Kolejka * WybKolejki(Kolejka * wk); // znajduje najkrotsza kolejke

int main(void) {
	Kolejka kol[OKIENKO_NR];
	Pozycja tymcz;					// dane o nowym kliencie
	Kolejka * najkrotsza;			// najkrotksza kolejka
	int godz;						// liczba godzin symulacji
	int nagodz;						// srednia liczba nowych klientow na godzine
	int okienko;					// aktualne okienko
	long cykl, gran_cyklu;			// licznik petli, granica
	long odeslani = 0;				// klienci odeslani z braku miejsca
	long klienci = 0;				// klienci, ktorzy weszli do kolejki
	long obsluzeni = 0;				// obsluzeni w czasie symulacji
	long suma_kol = 0;				// kumulatywna dlugosc kolejki
	int czas_czek = 0;				// czas do obsluzenia nastepnego klienta
	double min_na_kl;				// sredni czas miedzy przybylymi klientami
	long kol_czek = 0;				// kumulatywny czas stania w kolejce

	for(okienko=0; okienko < OKIENKO_NR; okienko++)
		InicjujKolejke(&kol[okienko]);
	srand(time(0));					// losowa inicjalizacja funkcji rand()
	puts("Studium przypadku: Punkt porad Zygmunta Prywaciarza");
	puts("Podaj liczbe godzin symulacji:");
	scanf("%d", &godz);
	gran_cyklu = MIN_W_GODZ * godz;
	puts("Podaj srednia liczbe klientow w ciagu godziny:");
	scanf("%d", &nagodz);
	min_na_kl = MIN_W_GODZ / nagodz;
	for(cykl = 0; cykl < gran_cyklu; cykl++) {
		if(nowyklient(min_na_kl)) {
			printf("cykl %ld: pojawil sie klient\n", cykl);
			najkrotsza = WybKolejki(kol);
			printf("najkrotsza: %p\nxxxxxxxx\n", najkrotsza);
			if(PelnaKolejka(najkrotsza))
				odeslani++;
			else {
				klienci++;
				tymcz = czasklienta(cykl);
				Ustaw(tymcz, najkrotsza);
			}
		}
		else
			printf("cykl %ld: brak klienta\n", cykl);
		if(czas_czek <= 0) {
			for(okienko = 0; okienko < OKIENKO_NR; okienko++) {
				if(!PustaKolejka(&kol[okienko])) {
					Odlacz(&tymcz, &kol[okienko]);
					czas_czek += tymcz.czaskons;
					kol_czek += (cykl - tymcz.przybycie);
					obsluzeni++;
				}
			}
		}
		if(czas_czek > 0)
			czas_czek--;
		for(okienko=0; okienko < OKIENKO_NR; okienko++)
			suma_kol += LiczbaPozycji(&kol[okienko]);
	}
	if(klienci > 0) {
		printf("klienci przyjeci do kolejki: %ld\n", klienci);
		printf("		  klienci obsluzeni: %ld\n", obsluzeni);
		printf("		   klienci odeslani: %ld\n", odeslani);
		printf("	srednia dlugosc kolejki: %.2f\n", (double) suma_kol / gran_cyklu);
		printf("	sredni czas oczekiwania: %.2f minut\n", (double) kol_czek / obsluzeni);
	}
	else
		puts("Brak klientow!");

	return 0;
}
/*
 * x = sredni czas w minutach miedzy wejsciem kolejnych klientow
 * wartoscia zwracana jest True, jesli w tej munucie pojawil sie klient
 */
bool nowyklient(double x) {
	if(rand() * x / RAND_MAX < 1)
		return true;
	else
		return false; // false
}
/*
 * kiedy jest czasem wejscia klienta do kolejki
 * funkcja zwraca strukture typu Pozycja z czasem przybycia
 * ustawionym na kiedy i czasem konsultacji ustawionym na
 * wartosc losowa z przedzialu 1 - 3
 */
Pozycja czasklienta(long kiedy) {
	Pozycja klient;

	klient.czaskons = 3; // rand() % 3 + 1;
	klient.przybycie = kiedy;

	return klient;
}
Kolejka * WybKolejki(Kolejka * wk) {
	int i, j;
	Kolejka * tymcz = NULL;

	for(i=0; i < OKIENKO_NR; i++) {
		printf("Kolejka %d: %d elementow ", i, LiczbaPozycji(&wk[i]));
		printf("adres: %p\n", &wk[i]);
	}
	for(i=0; i < OKIENKO_NR; i++) {
		for(j=i+1; j < OKIENKO_NR - i; j++) {
			if(LiczbaPozycji(&wk[i]) > LiczbaPozycji(&wk[j])) {
				tymcz = (wk+i);
				*(wk+i) = *(wk+j);
				*(wk+j) = *tymcz;
			}
		}
	}
	return &wk[0];
}
